
import _ from "lodash";

import { LogicServer } from "../../../LogicServer";
import { EnumCacheGroup } from "../../../../../common/enum/EnumCacheGroup";
import { EnumErrorCode } from "../../../../../common/enum/EnumErrorCode";
import { EnumRoomType } from "../../../../../common/enum/EnumRoomType";
import { GameBetOrderInfo } from "../../../../../common/model/GameBetOrderInfo";
import { GameRoomInfo } from "../../../../../common/model/GameRoomInfo";
import { CS_Bet } from "../../../../../common/protocols/Proto_Bet";
import { CacheComponent } from "../../../../../framework/service/Components/CacheComponent";
import { Tools } from "../../../../../framework/utils/Tools";
import { IRoomConfig } from "../../config/IRoomConfig";
import { UserEntity } from "../../controller/UserEntity";
import { IMsg } from "../../../../../framework/service/Components/WorkOrderInfo";
import { UserManager } from "../../controller/UserManager";


export interface IGameRoom extends GameRoomEntity { }
export abstract class GameRoomEntity {
    public uid: string = "";

    public data: GameRoomInfo = null;


    /**
     * 所有需要派发的奖励订单
     *
     * @private
     * @type {GameRewardOrder[]}
     * @memberof GameRoom
     */


    abstract type: EnumRoomType;

    public config: IRoomConfig = null;

    abstract start(): void;





    private _lastSaveTime: number = Tools.getServerTime();

    public setData(data: GameRoomInfo): void {
        this.data = data;

    }



    /**
     * 是否可以投注
     *
     * @abstract
     * @return {*}  {boolean}
     * @memberof GameRoomEntity
     */
    abstract canVote(): boolean;

    /**
     * 下注
     *
     * @abstract
     * @param {UserEntity} user
     * @param {CS_Bet} cs
     * @memberof GameRoomEntity
     */

    async vote(user: UserEntity, cs: CS_Bet): Promise<EnumErrorCode> {
        return new Promise((resove, reject) => {

            resove(EnumErrorCode.OK);
        });
    }
    abstract onUpdate(dt: number): void;


    abstract prizeDraw(): void;

    public setConfig(config: IRoomConfig): void {
        this.config = config;
    }

    public startNext(): void {

        this.data.startTime = Tools.getServerTime();
        this.data.prizeId += 1;
        this.data.expireTime = this.data.startTime + this.config.intervalTime;


    }

    public async saveOrder(user: UserEntity, bet: GameBetOrderInfo): Promise<EnumErrorCode> {

        return new Promise(async (resolve, reject) => {
            bet.createTime = Tools.getServerTime();

            const cacheComp: CacheComponent = <CacheComponent>LogicServer.entity.getComponent(CacheComponent);

            let orders: { [key: string]: GameBetOrderInfo } = await cacheComp.get(EnumCacheGroup.USER_ORDER, user.data.uid);


            if (!orders) {
                orders = {};
            }

            orders[bet.uid] = bet;
            await cacheComp.set(EnumCacheGroup.USER_ORDER, user.data.uid, bet);
            this.data.orders.push(bet);
            await cacheComp.set(EnumCacheGroup.ROOM_INFO, this.data.uid, this.data);
            resolve(EnumErrorCode.OK);
        });


    }


    //**数据落地 */
    public async save(): Promise<void> {
        this._lastSaveTime = Tools.getServerTime();
        const cacheComp: CacheComponent = <CacheComponent>LogicServer.entity.getComponent(CacheComponent);
        await cacheComp.set(EnumCacheGroup.ROOM_INFO, this.data.uid, this.data);
    }

    public update(servertime: number): void {

        if (servertime - this._lastSaveTime >= 5) {
            this.save();
        }


        if (this.data.expireTime - servertime <= 0) {
            this.prizeDraw();
            this.startNext();
        }
        this.onUpdate(servertime);
    }

    /**
     * 广播给
     *
     * @memberof GameRoomEntity
     */
    public notifyAllUser(msg:IMsg): void {
        _.each(this.data.onlineUsers, userid => {
            const user:UserEntity = UserManager.inst.getUser(userid);
            user?.send(msg);
        });
    }
}

